﻿using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 模拟器远程控制
{
    //运动设备接口定义
    public abstract partial class IMotionDevice : ObservableObject
    {

        [ObservableProperty]
        private bool connectState = false;

        [ObservableProperty]
        private bool faultState=false;


        //故障信息
        [ObservableProperty]
        private int errorCount = 0;
        public List<string> ErrorInfos { get; set; }=new List<string>();


        


        //用户配置和系统配置
        [ObservableProperty]
        private UserConfig? userConfig;

        [ObservableProperty]
        private SystemConfig systemConfig = new SystemConfig();


        //配置相关操作
        public void LoadUserConfig(string FileFullName = "UserConfig.cfg")
        {

        }

        public void ExportuserConfig(string FileFullName = "UserConfig.cfg")
        {
            try
            {
                string json = JsonConvert.SerializeObject(UserConfig, Formatting.Indented);
                System.IO.File.WriteAllText(FileFullName, json);
            }
            catch (Exception e)
            {

                throw new Exception($"保存用户配置失败{e.Message}");
            }
        }

        public void LoadSystemConfig(string FileFullName = "SystemConfig.cfg")
        {
            //读入配置文件
            try
            {
                string json = System.IO.File.ReadAllText(FileFullName);
                SystemConfig = JsonConvert.DeserializeObject<SystemConfig>(json);
            }
            catch (Exception e)
            {

                throw new Exception($"读取系统配置失败{e.Message}");
            }
            if (SystemConfig == null)
            {
                throw new Exception("读取系统配置失败");
            }

        }

        public void ExportSystemConfig(string FileFullName="SystemConfig.cfg")
        {
            try
            {
                string json = JsonConvert.SerializeObject(SystemConfig, Formatting.Indented);
                System.IO.File.WriteAllText(FileFullName, json);
            }
            catch (Exception e)
            {

                throw new Exception($"保存系统配置失败{e.Message}");
            }
        }

        //各轴
        [ObservableProperty]
        private ObservableCollection<MotionAxis> axes = new ObservableCollection<MotionAxis>();

        //转台启动
        public abstract void Boot();

        //转台关机
        public abstract void ShutDown();

        //转台重启
        public void ReBoot()
        {
            ShutDown();
            Thread.Sleep(1000);
            Boot();
        }

        //转台控制
        public abstract void Run(int ID,double Position,double Speed,bool Relative=false);
        public abstract void Run(int ID,double Speed);
        public abstract void CycleRun(int ID,double StartPosition,double MinPosition,double MaxPosition,double Step,int StepDelay_ms=500, int CycleCount=1);
        public abstract void Stop(int ID);
        public abstract void ClearZero(int ID);
        public abstract void FindZero(int ID);

        public abstract void SetLimit(int ID,double UpLimit,double DownLimit);

        public abstract void TriggerOpen(int ID);
        public abstract void TriggerSet(int ID,double StartPosition,double EndPosition,double Interval,int PulseWidth_us);
        public abstract void TriggerClose(int ID);
    }

    //轴定义
    public partial class MotionAxis : ObservableObject
    {
        [ObservableProperty]
        private bool selected;

        [ObservableProperty]
        private int iD;

        [ObservableProperty]
        private string name;

        [ObservableProperty]
        private bool enableState;

        [ObservableProperty]
        private double currentActualPosition;

        [ObservableProperty]
        private double positionOffset;

        private double currentDisplayPosition;
        public double CurrentDisplayPosition
        {
            get { return CurrentActualPosition+PositionOffset; }
        }

        [ObservableProperty]
        private double currentSpeed;




        private double setDisplayPosition;
        public double SetDisplayPosition
        {
            get => setDisplayPosition;
            set
            {
                
                SetProperty(ref setDisplayPosition, value);
                SetActualPosition= setDisplayPosition - PositionOffset;
            }
        }




        [ObservableProperty]
        private double setActualPosition=0.0;

        [ObservableProperty]
        private double setSpeed = 1.0;

        [ObservableProperty]
        private bool pulseTriggerSupport = true;

        [ObservableProperty]
        private double pulseTriggerStartPosition = 1.0;

        [ObservableProperty]
        private double pulseTriggerEndPosition = 2.0;

        [ObservableProperty]
        private double pulseTriggerInterval = 0.1;

        [ObservableProperty]
        private double pulseTriggerWidth = 10.0;

        [ObservableProperty]
        private double cycleStartPosition = 0;

        [ObservableProperty]
        private double cycleMinPosition = -10;

        [ObservableProperty]
        private double cycleMaxPosition = 10;

        [ObservableProperty]
        private double cycleStepPosition = 1;

        [ObservableProperty]
        private double cycleCount = 1;

        [ObservableProperty]
        private double cycleStepDelay = 100;

        [ObservableProperty]
        private string cycleInfo;

        [ObservableProperty]
        private bool cycleReachedCheck = true;


        [ObservableProperty]
        private bool sinSupport = false;

        [ObservableProperty]
        private float amplitude = 0.1f;
        [ObservableProperty]
        private int frequency = 1;
        [ObservableProperty]
        private int count = 1;
    }

    public partial class UserConfig : ObservableObject
    {
        [ObservableProperty]
        private bool select = false;

        [ObservableProperty]
        private string name = "";
    }

    public partial class SystemConfig : ObservableObject
    {
        [JsonIgnore]
        private string deviceName = "转台";
        [JsonProperty(Order = 1)]
        public string DeviceName
        {
            get { return deviceName; }
            set
            {
                SetProperty(ref deviceName, value);
            }
        }

        [JsonIgnore]
        private string model = "II-3";
        [JsonProperty(Order = 2)]
        public string Model
        {
            get { return model; }
            set
            {
                SetProperty(ref model, value);
            }
        }

        [JsonIgnore]
        private string vendor = "航天长屏科技有限公司";
        [JsonProperty(Order = 3)]
        public string Vendor
        {
            get { return vendor; }
            set
            {
                SetProperty(ref vendor, value);
            }
        }


        [JsonIgnore]
        private string setUpTime = "20230112";
        [JsonProperty(Order = 4)]
        public string SetUpTime
        {
            get { return setUpTime; }
            set
            {
                SetProperty(ref setUpTime, value);
            }
        }

        [JsonIgnore]
        private string version = "1.0";
        [JsonProperty(Order = 5)]
        public string Version
        {
            get { return version; }
            set
            {
                SetProperty(ref version, value);
            }
        }

        [JsonIgnore]
        private string lastModifyTime = "20240212";
        [JsonProperty(Order = 6)]
        public string LastModifyTime
        {
            get { return lastModifyTime; }
            set
            {
                SetProperty(ref lastModifyTime, value);
            }
        }

        [JsonIgnore]
        private int axisCount = 3;
        [JsonProperty(Order = 7)]
        public int AxisCount
        {
            get { return axisCount; }
            set
            {
                SetProperty(ref axisCount, value);
            }
        }
    }
}
